package cn.hebutrun.oulabot.websocket;

import cn.hebutrun.oulabot.common.Constants;
import cn.hebutrun.oulabot.common.util.ApiUtil;
import cn.hebutrun.oulabot.common.util.BotUtil;
import cn.hebutrun.oulabot.entity.enums.PostNoticeTypeEnum;
import cn.hebutrun.oulabot.entity.enums.PostRequestTypeEnum;
import cn.hebutrun.oulabot.entity.enums.PostTypeEnum;
import cn.hebutrun.oulabot.entity.response.BotMessageResponse;
import cn.hebutrun.oulabot.service.IMessageService;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONConfig;
import cn.hutool.json.JSONUtil;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.quartz.SchedulerException;

import javax.websocket.*;
import java.io.IOException;
import java.net.URI;

/**
 * @author zhaolong
 * @since 2022-09-27
 */
@Slf4j
@Getter
@ClientEndpoint
public class BotClient {
  private final Session session;
  private static BotClient INSTANCE;
  private final IMessageService iMessageService;
  private final ApiUtil apiUtil;

  private BotClient(IMessageService iMessageService, ApiUtil apiUtil) throws DeploymentException, IOException {
    this.iMessageService = iMessageService;
    this.apiUtil = apiUtil;
    session =
        ContainerProvider.getWebSocketContainer()
            .connectToServer(this, URI.create(Constants.BOT_WEBSOCKET_URL));
  }

  public static synchronized void connect(IMessageService iMessageService, ApiUtil apiUtil) {
    try {
      INSTANCE = new BotClient(iMessageService, apiUtil);
    } catch (DeploymentException | IOException e) {
      log.error(e.getMessage());
    }
  }

  @OnOpen
  public void onOpen(Session session) {
    log.info("oulabot连接成功");
  }

  @OnMessage
  public void onMessage(String msg) throws SchedulerException {
    BotMessageResponse botMessageResponse =
        JSONUtil.toBean(
            msg, JSONConfig.create().setIgnoreNullValue(true), BotMessageResponse.class);

    // 心跳包不处理
    if (PostTypeEnum.META_EVENT.getType().equals(botMessageResponse.getPostType())) {
      return;
    }

    System.out.println(msg);

    // 自动添加好友
    if (PostTypeEnum.REQUEST.getType().equals(botMessageResponse.getPostType())
        && PostRequestTypeEnum.FRIEND.getType().equals(botMessageResponse.getRequestType())) {
      BotUtil.addFriend(botMessageResponse.getFlag());
      return;
    }

    // 添加好友后自动发送使用说明
    if (PostTypeEnum.NOTICE.getType().equals(botMessageResponse.getPostType())
        && PostNoticeTypeEnum.FRIEND_ADD.getType().equals(botMessageResponse.getNoticeType())) {
      BotUtil.sendMessage(botMessageResponse, "欢迎使用oula-bot!");
      BotUtil.sendReadme(botMessageResponse);
      return;
    }

    if (StrUtil.startWith(botMessageResponse.getMessage(), "#")
        || StrUtil.startWith(botMessageResponse.getMessage(), "＃")) {
      iMessageService.onOrder(botMessageResponse);
    }
    BotUtil.markMsgAsRead(botMessageResponse.getMessageId());
  }

  @OnClose
  public void onClose(Session session) {
    log.info("oulabot连接关闭");
  }

  @OnError
  public void onError(Session session, Throwable throwable) throws InterruptedException {
    log.error(throwable.getMessage());
    log.warn("oulabot连接异常,将于5秒后尝试重新连接...");
    Thread.sleep(5000);
    // 尝试重新连接
    BotClient.connect(iMessageService, apiUtil);
  }

}
